package alarm;

import db.ColumnData;
import db.DBRecord;
import db.DataAccessObject;
import db.SQLDataTypes;
import db.TableField;

import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/*
 * The AlarmSystem is used to fetch pending notices from a database
 * 
 * @author Benjamin Landers
 * @author Colin Watson
 * 
 */
public class AlarmSystem
{

	DataAccessObject dao = new DataAccessObject("rsdb");

	TableField message = new TableField("message", SQLDataTypes.VARCHAR);
	TableField type = new TableField("type", SQLDataTypes.VARCHAR);
	TableField startDate = new TableField("startdate", SQLDataTypes.VARCHAR);
	TableField endDate = new TableField("enddate", SQLDataTypes.VARCHAR);

	// private String user;
	private String tableName;

	public AlarmSystem(String user)
	{
		// this.user = user;
		this.tableName = "notices_" + user;
		this.connectToDB();
		dao.createTable(tableName, startDate, endDate, message, type);
	}

	/*
	 * Adds a new notice to the table
	 * 
	 * @param notice is a Notice Object
	 */
	public void addNotice(Notice notice)
	{
		this.connectToDB();
		dao.addRecord(tableName, new ColumnData("startDate", notice
				.getStartDate().toString()), new ColumnData("endDate", notice
				.getEndDate().toString()), new ColumnData("message", notice
				.getMessage()), new ColumnData("type", notice.getType()));
		System.out.println("Added new notice " + notice);
		this.disconnectFromDB();
	}

	/*
	 * Removes a notice from the table
	 * 
	 * @param notice is Notice Object
	 */
	public void removeNotice(Notice notice)
	{
		dao.deleteRecord(tableName, new ColumnData("startDate", notice
				.getStartDate().toString()), new ColumnData("endDate", notice
				.getEndDate().toString()), new ColumnData("message", notice
				.getMessage()), new ColumnData("type", notice.getType()));
	}

	/*
	 * Remove all notices
	 */
	public void removeAllNotices()
	{
		dao.dropTable(tableName);
		dao.createTable(tableName, startDate, endDate, message, type);

	}

	/*
	 * Finds and returns all notices that have expired
	 */
	public List<Notice> expiredNotices()
	{
		Date currentDate = new Date();
		List<DBRecord> allRecords = dao.getAllRecords(tableName);
		Iterator<DBRecord> recordIterator = allRecords.iterator();
		List<Notice> result = new ArrayList<Notice>();

		SimpleDateFormat df = new SimpleDateFormat(
				"EEE MMM dd HH:mm:ss zzz yyyy");

		while (recordIterator.hasNext())
		{
			DBRecord record = recordIterator.next();
			try
			{
				Date recordStartDate = df.parse((String) record
						.getFieldValue("startDate"), new ParsePosition(0));
				Date recordEndDate = df.parse((String) record
						.getFieldValue("endDate"), new ParsePosition(0));
				if (currentDate.compareTo(recordEndDate) > 0)
				{
					result.add(new Notice(recordStartDate, recordEndDate,
							(String) record.getFieldValue("message"),
							(String) record.getFieldValue("type")));
				}
			} catch (Exception e)
			{
				// pass
			}
		}

		return result;
	}

	/*
	 * Finds and returns all notices that are pending
	 */
	public List<Notice> pendingNotices()
	{
		this.connectToDB();
		Date currentDate = new Date();
		List<DBRecord> allRecords = dao.getAllRecords(tableName);
		Iterator<DBRecord> recordIterator = allRecords.iterator();
		List<Notice> result = new ArrayList<Notice>();

		SimpleDateFormat df = new SimpleDateFormat(
				"EEE MMM dd HH:mm:ss zzz yyyy");

		while (recordIterator.hasNext())
		{
			DBRecord record = recordIterator.next();
			try
			{
				Date recordStartDate = df.parse((String) record
						.getFieldValue("startDate"), new ParsePosition(0));
				Date recordEndDate = df.parse((String) record
						.getFieldValue("endDate"), new ParsePosition(0));
				if (currentDate.compareTo(recordEndDate) < 0)
				{
					result.add(new Notice(recordStartDate, recordEndDate,
							(String) record.getFieldValue("message"),
							(String) record.getFieldValue("type")));
				}
			} catch (Exception e)
			{
				// pass
			}
		}
		this.disconnectFromDB();

		return result;
	}

	/*
	 * Returns all notices between now and specified time (in hours)
	 */
	public List<Notice> pendingNoticeUntilTime(Integer hours)
	{
		Date currentDate = new Date();
		Date futureDate = new Date((currentDate.getTime() + (long) hours
				.intValue() * 60 * 60000));
		List<DBRecord> allRecords = dao.getAllRecords(tableName);
		Iterator<DBRecord> recordIterator = allRecords.iterator();
		List<Notice> result = new ArrayList<Notice>();

		SimpleDateFormat df = new SimpleDateFormat(
				"EEE MMM dd HH:mm:ss zzz yyyy");

		while (recordIterator.hasNext())
		{
			DBRecord record = recordIterator.next();
			try
			{
				Date recordStartDate = df.parse((String) record
						.getFieldValue("startDate"), new ParsePosition(0));
				Date recordEndDate = df.parse((String) record
						.getFieldValue("endDate"), new ParsePosition(0));
				if (recordEndDate.after(currentDate)
						&& recordEndDate.before(futureDate))
				{
					result.add(new Notice(recordStartDate, recordEndDate,
							(String) record.getFieldValue("message"),
							(String) record.getFieldValue("type")));
				}
			} catch (Exception e)
			{
				// pass
			}
		}

		return result;
	}

	/*
	 * Returns all notices between now and specified Date
	 */
	public List<Notice> pendingNoticeUntilTime(Date date)
	{
		Date currentDate = new Date();
		Date futureDate = date;
		List<DBRecord> allRecords = dao.getAllRecords(tableName);
		Iterator<DBRecord> recordIterator = allRecords.iterator();
		List<Notice> result = new ArrayList<Notice>();

		SimpleDateFormat df = new SimpleDateFormat(
				"EEE MMM dd HH:mm:ss zzz yyyy");

		while (recordIterator.hasNext())
		{
			DBRecord record = recordIterator.next();
			try
			{
				Date recordStartDate = df.parse((String) record
						.getFieldValue("startDate"), new ParsePosition(0));
				Date recordEndDate = df.parse((String) record
						.getFieldValue("endDate"), new ParsePosition(0));
				if (recordEndDate.after(currentDate)
						&& recordEndDate.before(futureDate))
				{
					result.add(new Notice(recordStartDate, recordEndDate,
							(String) record.getFieldValue("message"),
							(String) record.getFieldValue("type")));
				}
			} catch (Exception e)
			{
				// pass
			}
		}

		return result;
	}

	/*
	 * Connect to the database
	 */

	public void connectToDB()
	{
		dao.connect();
	}

	/*
	 * Disconnect from the database
	 */
	public void disconnectFromDB()
	{
		dao.disconnect();
	}

	public static void main(String args[])
	{
		AlarmSystem spam = new AlarmSystem("e");
		/*
		 * Notice notice0 = new Notice(new Date(200, 2, 2), "notice0", "game");
		 * Notice notice1 = new Notice(new Date(0, 2, 2), "notice1", "game");
		 * Notice notice2 = new Notice(new Date(-2, 2, 2), "notice2", "game");
		 * Notice notice3 = new Notice(new Date(-200, 2, 2), "notice3",
		 * "notice");
		 * 
		 * spam.addNotice(notice0); spam.addNotice(notice1);
		 * spam.addNotice(notice2); spam.addNotice(notice3);
		 */

		List<Notice> foo = spam.pendingNotices();
		System.out.println(foo.size());
		for (int i = 0; i < foo.size(); i++)
		{
			System.out.println(foo.get(i));
		}
	}
}
